#include <iostream>
#include <string>
#include <math.h>
#include <fstream>
#include "TFloat.cpp"
#include <stdio.h>
#include <stdlib.h>
#include <iomanip>

using namespace std;

//FILE * CaidaSinRosamientoB = fopen("Caida sin rozamiento Biseccion.out", "w");
FILE * CaidaConRosamientoB = fopen("Caida con rozamiento Biseccion.out", "w");
//FILE * CaidaSinRosamientoN = fopen("Caida sin rozamiento Newton.out", "w");
FILE * CaidaConRosamientoN = fopen("Caida con rozamiento Newton.out", "w");
//FILE * CaidaSinRosamientoByN = fopen("Caida sin rozamiento Biseccion + Newton.out", "w");
FILE * CaidaConRosamientoByN = fopen("Caida con rozamiento Biseccion + Newton.out", "w");
FILE * EnergiaMecanica = fopen("Energia Mecanica.out", "w");

FILE * MiPrecBis = fopen("Precision biseccion.out", "w");
FILE * MiPrecNew = fopen("Precision newton.out", "w");
int listo = 0; // usada para guardar el test de la precision.

std::ofstream* out= new std::ofstream("Posicion Sin Rozamiento");
FILE *asd = fopen("Posicion Sin Rozamiento","w");
int precision;
TFloat cero (0, 52);
TFloat menosuno (-1, 52);
int cantBis;
int cantNew;
int debug = 1;
TFloat g (9.81, 52);
TFloat masa (15, 52);
TFloat e (exp(1), 52);




#define CantDeRebotes 2

TFloat tfloatAbs(TFloat x)
{
    if (x.dbl() >= cero.dbl())
        return x;
    else
        return x * menosuno;
}

TFloat posicionSinRozamiento(TFloat h, TFloat vi, TFloat x) //Función posición. Caso sin rozamiento.
{
    return (h + vi*x -(g/2)*x*x);
}

TFloat velocidadSinRozamiento(TFloat vi, TFloat x) //Función velocidad. Caso sin rozamiento
{
    return (vi-g*x);
}

TFloat posicionConRozamiento(TFloat h, TFloat vi, TFloat A, TFloat x) //Función posición. Caso con rozamiento
{
    return h + (vi/A) + (g/(A*A)) - (g*x/A) - ((vi/A) + (g/(A*A)))*(menosuno*A*x).exponencial();
}

TFloat velocidadConRozamiento(TFloat vi, TFloat A, TFloat x) //Función velocidad. Caso con rozamiento
{
    return ((vi + g/A)*(menosuno*A*x).exponencial()) - g/A;
}

TFloat veloDerivSin(TFloat vi, TFloat x) //Derivada de la velocidad. Caso sin rozamiento
{
    return menosuno*g;
}

TFloat veloDerivCon(TFloat vi, TFloat A, TFloat x) //Derivada de la velocidad. Caso con rozamiento
{
    return (vi+g/A)*(menosuno*A*x).exponencial()*menosuno*A;
}

TFloat impactoCon(TFloat fr, TFloat vi, TFloat A, TFloat x)
{
    return (menosuno * fr * velocidadConRozamiento(vi, A, x));
}

TFloat impactoSin(TFloat fr, TFloat vi, TFloat x)
{
    return (menosuno * fr * velocidadSinRozamiento(vi, x));
}

TFloat posConRozamientoBiseccion(TFloat h, TFloat vi, TFloat A, TFloat a, TFloat b, TFloat error,int n)
{
    TFloat m;

    if (posicionConRozamiento(h, vi, A, a).dbl() * posicionConRozamiento(h, vi, A, b).dbl() >= 0)
    {
        cout << "FAIL (Posicion Con Rozamiento Biseccion)" << endl;
        cout << "f(a) = "<<posicionConRozamiento(h, vi, A, a).dbl()<< endl;
        cout << "f(b) = "<<posicionConRozamiento(h, vi, A, b).dbl()<< endl;
        cout << "a = "<<a.dbl()<<endl;
        cout << "b = "<<b.dbl()<<endl;
        cout << "Precision " << precision<<endl;
        return 1;
    }
    int cant=0;
    TFloat dos(2, precision);
    while(b.dbl() - a.dbl() > error.dbl() && cant<n)
    {
        m = (a + b)/ dos;
        TFloat x ((posicionConRozamiento(h, vi, A, a) * posicionConRozamiento(h, vi, A, m)).dbl(), precision);
        if (x.dbl() < 0)
        {
            b = m;
        }
        else if (x.dbl() > 0)
        {
             a = m;
        }
        else
        {
            break;
        }
        cant++;
    }
    cantBis = cant;
    return m;
}




TFloat posSinRozamientoBiseccion(TFloat h, TFloat vi, TFloat a, TFloat b, TFloat error,  int n)
{
    TFloat m;
    if (posicionSinRozamiento(h, vi, a).dbl() * posicionSinRozamiento(h, vi, b).dbl() >= 0)
    {
        cout << "FAIL (Posicion Sin Ronzamiento Biseccion)" << endl;
        cout << "f(a) = "<<posicionSinRozamiento(h, vi, a).dbl() << endl;
        cout << "f(b) = "<<posicionSinRozamiento(h, vi, b).dbl() << endl;
        cout << "a = "<<a.dbl()<<endl;
        cout << "b = "<<b.dbl()<<endl;
        return 1;
    }
    int cant=0;
    while(b.dbl() - a.dbl() > error.dbl() && cant<n)
    {
        m = (a + b)/ 2;
        if (posicionSinRozamiento(h, vi, a).dbl() * posicionSinRozamiento(h, vi, m).dbl() < 0)
        {
            b = m;
        }
        else if (posicionSinRozamiento(h, vi, m).dbl() * posicionSinRozamiento(h, vi, b).dbl() < 0)
        {
            a = m;
        }
        else
        {
            break;
        }
        cant++;
    }
    cantBis = cant;
    return m;
}

TFloat posConRozamientoNewton(TFloat h, TFloat vi, TFloat A, TFloat xf, TFloat error,   int it)
{
    TFloat xi;
    int i = 0;
    do
    {
        xi = xf;
        xf = xi - posicionConRozamiento(h, vi, A, xi)/velocidadConRozamiento(vi, A, xi);
        i++;
        if(fabs(xf.dbl() - xi.dbl()) < error.dbl()) cantNew = i;

    }
    while(fabs((xf - xi).dbl()) > error.dbl()  && i < it);
cantNew = i;
    return xf;
}



TFloat posSinRozamientoNewton(TFloat h, TFloat vi, TFloat xf, TFloat error, int cant)
{
    int i = 0;
    TFloat xi;
    do
    {
        xi = xf;
        xf = xi - posicionSinRozamiento(h, vi, xi)/velocidadSinRozamiento(vi, xi);
        i++;
        //*out<<fabs(xf.dbl() - xi.dbl())<<endl;
    }
    while(fabs(xf.dbl() - xi.dbl()) > error.dbl() && i<cant);
cantNew = i;
    return xf;
}

TFloat velocidadBiseccionCon(TFloat vi, TFloat A, TFloat a, TFloat b, TFloat error,  int n)
{
    TFloat m;
    if (velocidadConRozamiento(vi, A, a).dbl() * velocidadConRozamiento(vi, A, b).dbl() >= 0)
    {
        cout << "FAIL (Velocidad Biseccion Con Rozamiento) " << endl;
        cout << "f(a) = "<<velocidadConRozamiento(vi, A, a).dbl() << endl;
        cout << "f(b) = "<<velocidadConRozamiento(vi, A, b).dbl() << endl;
        cout << "a = "<<a.dbl()<<endl;
        cout << "b = "<<b.dbl()<<endl;
        cout << "vi = "<<vi.dbl()<<endl;
        cout << "A = "<<A.dbl()<<endl;
        cout << "Precision " << precision<<endl;
        return 1;
    }
    int cant= 0;
    while(b.dbl() - a.dbl() > error.dbl() && cant<n)
    {
        m = (fabs((a.dbl() + b.dbl()))/ 2);
        if (velocidadConRozamiento(vi, A, a).dbl() * velocidadConRozamiento(vi, A, m).dbl() < 0)
        {
            b = m;
        }else if (velocidadConRozamiento(vi, A, m).dbl() * velocidadConRozamiento(vi, A, b).dbl() < 0)
        {
            a = m;
        }else
        {
            break;
        }
        cant++;
    }
    cantBis = cant;
    return m;
}

TFloat velocidadBiseccionSin(TFloat vi, TFloat a, TFloat b, TFloat error,   int n)
{
    TFloat m;
    if (velocidadSinRozamiento(vi, a).dbl() * velocidadSinRozamiento(vi, b).dbl() >= 0)
    {
        cout << "FAIL (Velocidad Biseccion Sin Rozamiento)" << endl;
        cout << "f(a) = "<< velocidadSinRozamiento(vi, a).dbl()<< endl;
        cout << "f(b) = "<< velocidadSinRozamiento(vi, b).dbl()<< endl;
        cout << "a = "<<a.dbl()<<endl;
        cout << "b = "<<b.dbl()<<endl;
        return 1;
    }
    int cant= 0;
    while(b.dbl() - a.dbl() > error.dbl() && cant<n)
    {
        m = (fabs((a.dbl() + b.dbl()))/ 2);
        if (velocidadSinRozamiento(vi, a).dbl() * velocidadSinRozamiento(vi, m).dbl() < 0)
        {
            b = m;
        }else if (velocidadSinRozamiento(vi, m).dbl() * velocidadSinRozamiento(vi, b).dbl() < 0)
        {
            a = m;
        }else
        {
            break;
        }
        cant++;
    }
    cantBis = cant;
    return m;
}


TFloat velocidadNewtonCon(TFloat vi, TFloat A, TFloat xf, TFloat error, int cant)
{
    int i=0;
    TFloat xi;
    do
    {

        xi = xf;
        xf = xi - (velocidadConRozamiento(vi, A, xi)/veloDerivCon(vi, A, xi));

        i++;
    }
    while(fabs(xf.dbl() - xi.dbl()) > error.dbl() && i<cant);

    return xf;
}

TFloat velocidadNewtonSin(TFloat vi, TFloat xf, TFloat error, int cant)
{
    TFloat xi;
    int i = 0;

    do
    {
        xi = xf;
        xf = xi - (velocidadSinRozamiento(vi, xi)/veloDerivSin(vi, xi));
        i++;
    }
    while(fabs(xf.dbl() - xi.dbl()) > error.dbl() && i<cant);
cantNew = i;
    return xf;
}

TFloat eMecanicaCon(TFloat h, TFloat vi, TFloat A, TFloat t)
{
    TFloat dos (2, precision);
    TFloat y = velocidadConRozamiento(vi, A, t);
    return(g*posicionConRozamiento(h, vi, A, t)+(y * y/dos));
}

TFloat eMecanicaSin(TFloat h, TFloat vi,  TFloat t)
{
    TFloat dos (2, precision);
    TFloat y = velocidadSinRozamiento(vi, t);
    return(g*posicionSinRozamiento(h, vi, t)+(y * y/dos));
}


void primerImpactoConRozamientoBiseccion(TFloat h, TFloat vi, TFloat A, TFloat fr, TFloat ErrorNewton, TFloat ErrorBisec)
{
    fprintf(CaidaConRosamientoB ,"DATOS DEL PRIMER IMPACTO: \n\nIteraciones \tCero \n\n");
    TFloat cero;
    TFloat error(0.1, precision);
    TFloat fin(0.0000001, precision);
    TFloat diez(10, precision);

    for(int i =2; i<40; i++)
    {
        cout<<"llega A"<<endl;
        cero = posConRozamientoBiseccion(h, vi, A, TFloat(0.00000000001, precision), TFloat(50, precision), ErrorBisec,i);
        fprintf(CaidaConRosamientoB ,"%d\t%5.52f\n",i,cero.dbl());
        cout<<"llega A"<<endl;
    }
    fprintf(CaidaConRosamientoB ,"\n\nError \tIteraciones \n\n");


    while(error.dbl() > fin.dbl())
    {
        cout<<"llega B"<<endl;
        cero = posConRozamientoBiseccion(h, vi, A, TFloat(0.00000000001, precision), TFloat(50, precision), error,10000);
        fprintf(CaidaConRosamientoB ,"%5.20f\t%d\n",error.dbl(),cantBis);
        error = error/diez;
        cout<<"llega C"<<endl;
    }
    cout<<"llega Z"<<endl;
}

void primerImpactoConRozamientoNewton(TFloat h, TFloat vi, TFloat A, TFloat fr, TFloat ErrorNewton, TFloat ErrorBisec)
{
    fprintf(CaidaConRosamientoN, "DATOS DEL PRIMER IMPACTO: \n\nX0 \tCero \n\n");
    // cero, variando x0
    TFloat xf(0,precision);
    TFloat uno(1,precision);
    TFloat cero;
//
//    while(xf.dbl() < 50)
//    {
//        cero = posConRozamientoNewton(h, vi, A, xf, ErrorNewton, 100000);
//        fprintf(CaidaConRosamientoN, "%5.2f\t%5.52f\n",xf.dbl(),cero.dbl());
//        xf = xf + uno;
//        cout<<"llega M: "<<xf.dbl()<<"\t"<<uno.dbl()<<endl;
//    }

    // x0 = 11
    TFloat once(11,precision);
    fprintf(CaidaConRosamientoN, "\nPara x0 = 11 \nIteraciones \tCero\n");
    for(int i = 1; i < 40; i++)
    {
        cero = posConRozamientoNewton(h, vi, A, once, ErrorNewton, i);
        fprintf(CaidaConRosamientoN,"%d\t%5.52f\n",i, cero.dbl());
    }
    // x0 = 24
    TFloat veinticuatro(24, precision);
    fprintf(CaidaConRosamientoN, "\nPara x0 = 24 \nIteraciones \tCero\n");
    for(int i = 1; i < 40; i++)
    {
        cero = posConRozamientoNewton(h, vi, A, veinticuatro, ErrorNewton, i);
        fprintf(CaidaConRosamientoN,"%d\t%5.52f\n",i, cero.dbl());
    }
    // x0 = 100
    TFloat cien(100,precision);
    fprintf(CaidaConRosamientoN, "\nPara x0 = 100 \nIteraciones \tCero\n");
    for(int i = 1; i < 40; i++)
    {
        cero = posConRozamientoNewton(h, vi, A, cien, ErrorNewton, i);
        fprintf(CaidaConRosamientoN,"%d\t%5.52f\n",i, cero.dbl());
    }
    // iteraciones variando el error
    TFloat error(0.1, precision);
    TFloat diez(10, precision);
    TFloat fin(0.00000000000001, precision);
    fprintf(CaidaConRosamientoN, "\n\nError \tIteraciones \n\n");
    while(error.dbl() > fin.dbl())
    {
        cero = posConRozamientoNewton(h, vi, A, veinticuatro, error, 10000);
        fprintf(CaidaConRosamientoN ,"%5.20f\t%d\n",error.dbl(),cantNew);
        error = error / diez;
    }
}

void primerImpactoConRozamientoBiseccionYNewton(TFloat h, TFloat vi, TFloat A, TFloat fr, TFloat ErrorNewton, TFloat ErrorBisec)
{
    //cout<<"entre pos sin roz bi"<<endl;
    fprintf(CaidaConRosamientoByN, "DATOS DEL PRIMER IMPACTO: \n\nIteraciones \tCero \n\n");
    // cero, variando iteraciones
    TFloat cero;
    TFloat error(0.1, precision);
    TFloat fin(0.00000000000001, precision);
    TFloat diez(10, precision);
    TFloat xf = posConRozamientoBiseccion(h, vi, A, TFloat(20, precision), TFloat(50, precision), ErrorBisec,1);

    for(int i =2; i<40; i++)
    {
        cero = posConRozamientoNewton(h, vi, A, xf, ErrorNewton, i);
        fprintf(CaidaConRosamientoByN ,"%d\t%5.52f\n",i,cero.dbl());
    }
    fprintf(CaidaConRosamientoByN, "\n\nError \tIteraciones \n\n");
    while(error.dbl() > fin.dbl())
    {
        cero = posConRozamientoNewton(h, vi, A, xf, error, 10000);
        fprintf(CaidaConRosamientoByN ,"%5.20f\t%d\n",error.dbl(),cantNew);
        error = error / diez;
    }
}

void testCaidaSinRozamientoBiseccion(TFloat h, TFloat vi, TFloat fr, TFloat ErrorBisec, TFloat a, TFloat b, int n,  char *fileName)
{
	out = new std::ofstream(fileName);
    cout<<"Test Caida Sin Rozamiento Biseccion"<<endl;
    *out<<"Usando el metodo de Biseccion"<<endl<<endl<<endl;

    TFloat PrimerRebote, SegundoRebote, AlturaMaxima, Energia;
    int cantIteracionesPrimerCero,cantIteracionesSegundoCero,cantIteracionesVelocidadCero; ///aca
    TFloat cero = posSinRozamientoBiseccion(h, vi, a, b, ErrorBisec,n);
    cantIteracionesPrimerCero = cantBis;            ///aca

    PrimerRebote = cero;
    SegundoRebote = cero;

    Energia = eMecanicaSin(h, vi, 0);

    vi = impactoSin(fr, vi, cero);
    h = 0;
    cero = posSinRozamientoNewton(h, vi, cero, ErrorBisec, n);
    cantIteracionesSegundoCero = cantBis;       ///aca

    Energia = Energia - eMecanicaSin(h, vi, cero);

    SegundoRebote = SegundoRebote + cero;
    AlturaMaxima = velocidadBiseccionSin(vi, a, b, ErrorBisec, n);
    cantIteracionesVelocidadCero = cantBis;     ///aca
    AlturaMaxima = posicionSinRozamiento(h, vi, AlturaMaxima);

    *out << endl <<"Momento del 1er rebote: " << PrimerRebote.dbl()<<"\t #iteraciones = "<<cantIteracionesPrimerCero << endl; ///aca
    *out << endl << "Momento del 2do rebote: " << SegundoRebote.dbl()<<"\t #iteraciones = "<<cantIteracionesSegundoCero<< endl; ///aca
    *out << endl << "ALTURA MAXIMA: " << AlturaMaxima.dbl()<< "\t #iteraciones para encontrar el t = "<<cantIteracionesVelocidadCero <<endl;    ///aca
    *out << endl << "DIFERENCIA DE ENERGIA: " << Energia.dbl()  << endl<<endl<<endl<<endl<<"---------------------------------------------------------------------------------------------------------------" << endl<<endl<<endl<<endl;  ///aca
    fprintf(EnergiaMecanica,"Energia mecanica: %5.52f\n",Energia.dbl());

}
void testCaidaSinRozamientoNewton(TFloat h, TFloat vi, TFloat fr, TFloat ErrorNewton, TFloat x0, int n, char *fileName)
{
	out = new std::ofstream(fileName);
    cout<<"Test Caida Sin Rozamiento Newton"<<endl;
    *out<<"Usando el metodo de Newton"<<endl<<endl<<endl;

    TFloat PrimerRebote, SegundoRebote, AlturaMaxima, Energia;
    int cantIteracionesPrimerCero,cantIteracionesSegundoCero,cantIteracionesVelocidadCero;
    TFloat cero = posSinRozamientoNewton(h, vi,x0, ErrorNewton, n);
    cantIteracionesPrimerCero = cantNew;            ///aca

    PrimerRebote = cero;
    SegundoRebote = cero;

    Energia = eMecanicaSin(h, vi, 0);
    vi = impactoSin(fr, vi, cero);
    h = 0;
    cero = posSinRozamientoNewton(h, vi, cero, ErrorNewton, n);
    cantIteracionesSegundoCero = cantNew;       ///aca

    Energia = Energia - eMecanicaSin(h, vi, cero);

    SegundoRebote = SegundoRebote + cero;
    AlturaMaxima = velocidadNewtonSin(vi, x0, ErrorNewton, n);
    cantIteracionesVelocidadCero = cantNew;     ///aca
    AlturaMaxima = posicionSinRozamiento(h, vi, AlturaMaxima);

    *out<<endl;
    *out << endl << "X0 = " << x0.dbl()<<endl;
    *out << endl <<"Momento del 1er rebote: " << PrimerRebote.dbl()<<"\t #iteraciones = "<<cantIteracionesPrimerCero << endl; ///aca
    *out << endl << "Momento del 2do rebote: " << SegundoRebote.dbl()<<"\t #iteraciones = "<<cantIteracionesSegundoCero<< endl; ///aca
    *out << endl << "ALTURA MAXIMA: " << AlturaMaxima.dbl()<< "\t #iteraciones para encontrar el t = "<<cantIteracionesVelocidadCero <<endl;    ///aca
    *out << endl << "DIFERENCIA DE ENERGIA: " << Energia.dbl()  << endl<<endl<<endl<<endl<<"---------------------------------------------------------------------------------------------------------------" << endl<<endl<<endl<<endl;  ///aca
    fprintf(EnergiaMecanica,"Energia mecanica: %5.52f\n",Energia.dbl());
}
void testCaidaSinRozamientoBiseccionYNewton(TFloat h, TFloat vi, TFloat fr, TFloat ErrorNewton, TFloat ErrorBisec, TFloat a, TFloat b, int n, char *fileName)
{
    out = new std::ofstream(fileName);
    cout<<"Test Caida Sin Rozamiento Biseccion+Newton"<<endl;
    *out<<"Usando el metodo de Biseccion+Newton"<<endl<<endl<<endl;
    int cantIteracionesPrimerCeroB,cantIteracionesSegundoCeroB,cantIteracionesVelocidadCeroB;
    int cantIteracionesPrimerCeroN,cantIteracionesSegundoCeroN,cantIteracionesVelocidadCeroN;
    TFloat PrimerRebote, SegundoRebote, AlturaMaxima, Energia;
    TFloat cero = posSinRozamientoBiseccion(h, vi, a, b, ErrorBisec,n);
    cantIteracionesPrimerCeroB = cantBis;
    cero = posSinRozamientoNewton(h, vi,cero, ErrorNewton, n);
    cantIteracionesPrimerCeroN = cantNew;
    PrimerRebote = cero;
    SegundoRebote = cero;
    Energia = eMecanicaSin(h, vi, 0);
    vi = impactoSin(fr, vi, cero);
    h = 0;
    cero = posSinRozamientoBiseccion(h, vi, TFloat(0.00001, precision), b, ErrorBisec,n);
    cantIteracionesSegundoCeroB = cantBis;
    cero = posSinRozamientoNewton(h, vi,cero, ErrorNewton, n);
    cantIteracionesSegundoCeroN = cantNew;
    Energia = Energia - eMecanicaSin(h, vi, cero);
    SegundoRebote = SegundoRebote + cero;
    AlturaMaxima = velocidadBiseccionSin(vi, a, b, ErrorBisec, n);
    cantIteracionesVelocidadCeroB = cantBis;
    AlturaMaxima = velocidadNewtonSin(vi, AlturaMaxima, ErrorNewton,n);
    cantIteracionesVelocidadCeroN = cantNew;
    AlturaMaxima = posicionSinRozamiento(h, vi, AlturaMaxima);
    *out << endl << "Momento del 1er rebote: " << PrimerRebote.dbl()<<"\t #iteraciones de Biseccion = "<<cantIteracionesPrimerCeroB<<"\t #iteraciones de Newton = "<<cantIteracionesPrimerCeroN <<"\t #iteraciones total = "<<cantIteracionesPrimerCeroN + cantIteracionesPrimerCeroB << endl; ///aca
    *out << endl << "Momento del 2do rebote: " << SegundoRebote.dbl()<<"\t #iteraciones de Biseccion = "<<cantIteracionesSegundoCeroB<<"\t #iteraciones de Newton = "<<cantIteracionesSegundoCeroN <<"\t #iteraciones total = "<<cantIteracionesSegundoCeroN + cantIteracionesSegundoCeroB << endl; ///aca
    *out << endl << "ALTURA MAXIMA: " << AlturaMaxima.dbl()<<"\t #iteraciones de Biseccion para encontrar el t = "<<cantIteracionesVelocidadCeroB<<"\t #iteraciones de Newton para encontrar el t = "<<cantIteracionesVelocidadCeroN<<"\t #iteraciones total para encontrar el t = "<<cantIteracionesVelocidadCeroN + cantIteracionesVelocidadCeroB <<endl;    ///aca
    *out << endl << "DIFERENCIA DE ENERGIA: " << Energia.dbl()  << endl;
    fprintf(EnergiaMecanica,"Energia mecanica: %5.52f\n",Energia.dbl());
}


void testCaidaConRozamiento(TFloat h, TFloat vi, TFloat A, TFloat fr, TFloat ErrorNewton, TFloat ErrorBisec, char *fileName)
{
    out = new std::ofstream(fileName);
    TFloat PrimerRebote, SegundoRebote, AlturaMaxima, Energia;
    cout<<"llega D"<<endl;
    TFloat cero = posConRozamientoBiseccion(h, vi, A, TFloat(0, precision), TFloat(50, precision), ErrorBisec,10000);
    cout<<"llega E"<<endl;
    TFloat precBis = cero;

    cero = posConRozamientoNewton(h, vi, A, cero, ErrorNewton, 10000);
    TFloat precNewton = cero;

    if (!listo)
    {
    	fprintf(MiPrecBis, "%d %5.6f", precision, precBis.dbl());
    	fprintf(MiPrecNew, "%d %5.6f", precision, precNewton.dbl());
    	listo = 1;
    }

    PrimerRebote = cero;
    SegundoRebote = cero;
    Energia = eMecanicaCon(h, vi, A, 0);

    TFloat uno (1.0,precision);
    TFloat ceroCinco (0.5,precision);
    int cant = 0;
    TFloat i (0, precision);
    for(i =0; i.dbl()<(cero+uno).dbl(); i = i + ceroCinco)
    {
        if (cero.dbl() < i.dbl())
        {
            cant++;

            vi = impactoCon(fr, vi, A, i);
            i = 0;
            h = 0;
            cero = posConRozamientoNewton(h, vi, A, cero, ErrorNewton, 10000);
            Energia = Energia - eMecanicaCon(h, vi, A, cero);

            if(cant == 1)
            {
                SegundoRebote = SegundoRebote + cero;
                AlturaMaxima = velocidadBiseccionCon(vi, A, TFloat(0.00001,precision), TFloat(150,precision), ErrorBisec, 40);
                AlturaMaxima = velocidadNewtonCon(vi, A, AlturaMaxima, ErrorNewton,10000);
                AlturaMaxima = posicionConRozamiento(h, vi, A, AlturaMaxima);
            }
        }

        *out << "Posicion: " << posicionConRozamiento(h, vi, A, i).dbl() << "    EL t: " << i.dbl() << endl;

        if(cant == CantDeRebotes)
        {
            *out << endl <<"Momento del 1er rebote: " << PrimerRebote.dbl() << endl;
            *out << endl << "Momento del 2do rebote: " << SegundoRebote.dbl() << endl;
            break;
        }
    }

    *out << endl << "ALTURA MAXIMA: " << AlturaMaxima.dbl()  << endl;
    *out << endl << "DIFERENCIA DE ENERGIA: " << Energia.dbl() << endl;
    fprintf(EnergiaMecanica,"Energia mecanica: %5.52f\n",Energia.dbl());

}

void testCaidaSinRozamiento(TFloat h, TFloat vi, TFloat fr, TFloat ErrorNewton, TFloat ErrorBisec, TFloat x0,TFloat a,TFloat b, int n, char *fileName){

	//char[1024] salida;

//    for(i=2;i<=40;i++){
//sprintf(salida, "Sin Rozamiento Biseccion %d| python graphsched.py > Pruebas/jojo%d.png\n",nros[i],i);
// printf ("%s",testo);
// system(testo);
//}
    testCaidaSinRozamientoBiseccion(h,vi,fr,ErrorBisec,a,b,n,fileName);
    testCaidaSinRozamientoNewton(h,vi,fr,ErrorNewton,x0,n,fileName);
    testCaidaSinRozamientoBiseccionYNewton(h, vi, fr, ErrorNewton, ErrorBisec, a, b,n,fileName);
}



int main(int argc, char *argv[])
{
    char *fileName;


    if (argc == 10)
    {
        precision = (int)atof(argv[8]);
        TFloat h ((double)atof(argv[1]), precision);
        TFloat vi ((double)atof(argv[2]), precision);
        masa = TFloat((double)atof(argv[3]), precision);
        TFloat cr ((double)atof(argv[4]), precision);
        TFloat A = cr/masa;
        TFloat fr ((double)atof(argv[5]), precision);
        TFloat ErrorNewton ((double)atof(argv[6]), precision);
        TFloat ErrorBisec ((double)atof(argv[7]),precision);
        fileName = argv[9];

        g.set_precision(precision); menosuno.set_precision(precision); cero.set_precision(precision); e.set_precision(precision);

        cout << "h: " << h.dbl() << " / v0: " << vi.dbl() << " / masa: " << masa.dbl() << " / cr: " << cr.dbl() << " / fr: " << fr.dbl();
        cout << " / alpha: " << A.dbl() << " / g: "<< g.dbl() <<" / ErrorNewton: " << ErrorNewton.dbl() << " / ErrorBisec: " << ErrorBisec.dbl();
        cout << " / precision: " << precision << " / file: " << fileName << endl;

        testCaidaSinRozamiento(h, vi,    fr, ErrorNewton, ErrorBisec, TFloat(55,precision),TFloat(0,precision),TFloat(50,precision),10000, fileName);

        testCaidaConRozamiento(h, vi, A, fr, ErrorNewton, ErrorBisec,fileName);

        primerImpactoConRozamientoBiseccion(h, vi, A, fr, ErrorNewton, ErrorBisec);
        cout<<"llega X"<<endl;
        primerImpactoConRozamientoNewton(h, vi, A, fr, ErrorNewton, ErrorBisec);	//Asi solo no tiene sentido
        cout<<"llega Y"<<endl;
        primerImpactoConRozamientoBiseccionYNewton(h, vi, A, fr, ErrorNewton, ErrorBisec);

        TFloat frVariable (0.05, precision);
        TFloat aumento(0.05, precision);
        fprintf(EnergiaMecanica, "Factor de restitución:\n\n");

        while(frVariable.dbl() < 1)
        {
            fprintf(EnergiaMecanica, "%5.6f",frVariable.dbl());

            testCaidaConRozamiento(h, vi, A, frVariable, ErrorNewton, ErrorBisec,fileName);
            frVariable = frVariable + aumento;
        }


        TFloat crVariable (0.5, precision);
        TFloat AVariable;
        TFloat aumento2(0.5, precision);
       fprintf(EnergiaMecanica, "\n\nCoeficiente de rozamiento:\n\n");
        while(crVariable.dbl() <= 10)
        {
           AVariable = crVariable/masa;
            fprintf(EnergiaMecanica, "%5.6f",AVariable.dbl());

            testCaidaConRozamiento(h, vi, AVariable, fr, ErrorNewton, ErrorBisec,fileName);
            crVariable = crVariable + aumento2;
        }
    }
    else
    {
        cout << "Te faltan parametros" << endl;
    }

    return 0;
}
